package calao.contact.client;

import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;

import calao.client.ServiceCallback;
import calao.client.ui.CountryBox;
import calao.client.ui.Form;
import calao.client.ui.HasTitle;
import calao.client.ui.NumberFormat;
import calao.client.ui.RegexTextBox;
import calao.client.ui.Widgets;

public class ContactForm 
extends Form 
implements HasTitle
{
	
	class CreateCallback extends ServiceCallback {
		protected void onReturn(Object obj) {
			mod.refreshContacts();
			mod.getDesktop().setView(new ContactForm((Contact)obj, Form.VIEW, true));
		}
	}
	
	class SaveCallback extends ServiceCallback {
		Contact info;
		SaveCallback(Contact info) {
			this.info = info;
		}
		protected void onReturn(Object obj) {
			setChangesSaved();
			if (!ContactForm.this.info.name.equals(info.name)) {
				mod.refreshContacts();
			}
			ContactForm.this.info = info;
			reset();
		}		
	}
	
	final NumberFormat vatRateFormat = new NumberFormat("#0.0#"); 
	
	final ContactMod mod = ContactMod.instance;
	
	Contact info;
	
	final RegexTextBox nameBox = new RegexTextBox(".+");
	TextBox phoneBox = Widgets.newSmallTextBox();
	TextBox faxBox = Widgets.newSmallTextBox();
	TextBox emailBox = Widgets.newTextBox();
	ContactGroupBox groupBox = new ContactGroupBox();
	TextArea addressBox = new TextArea();
	TextBox townBox = Widgets.newTextBox();
	TextBox postCodeBox = Widgets.newTextBox(10);
	CountryBox countryBox = new CountryBox();
	TextArea notesBox = new TextArea();
		
	TextBox firstNameBox = Widgets.newTextBox();
	OrganizationBox orgBox;
	
	TextBox vatRateBox = Widgets.newSmallTextBox(); 
	TextBox vatNumberBox = Widgets.newTextBox(); 
	TextBox companyNumberBox = Widgets.newTextBox(); 
	
	ContactForm(Contact info, int action, boolean editable)
	{
		super(action, editable);
		this.info = info;
		if (action==CREATE) setTitle(mod.text.newContact());
		else setTitle(info.getLabel());
		add(mod.text.contactType(), info instanceof Person? mod.text.person()
				: mod.text.organization());
		add(mod.text.name(), nameBox);
		if (info instanceof Person) {
			add(mod.text.firstName(), firstNameBox);
			orgBox = new OrganizationBox();
			if (orgBox.getItemCount()>0) add(mod.text.organization(), orgBox);
		}
		add(mod.text.phone(), phoneBox);
		add(mod.text.fax(), faxBox);
		add(mod.text.email(), emailBox);
		addressBox.setVisibleLines(2);
		addressBox.setCharacterWidth(40);
		add(mod.text.address(), addressBox);
		add(mod.text.postCode(), postCodeBox);
		add(mod.text.town(), townBox);
		add(mod.text.country(), countryBox);
		if (info instanceof Organization) {
			add(mod.text.vatRate(), vatRateBox);
			add(mod.text.vatNumber(), vatNumberBox);
			add(mod.text.companyNumber(), companyNumberBox);
		}
		if (groupBox.getItemCount()>0) add(mod.text.groups(), groupBox);
		notesBox.setVisibleLines(3);
		notesBox.setCharacterWidth(80);
		add(mod.text.notes(), notesBox);
		reset();
	}

	ContactForm(Contact info)
	{
		this(info, CREATE, true);
	}
	
	public void reset()
	{
		nameBox.setText(info.name);
		phoneBox.setText(info.phone);
		emailBox.setText(info.email);
		faxBox.setText(info.fax);
		groupBox.setNumberSelected(info.groups);
		groupBox.refresh();
		setAddress(info.getAddress());
		notesBox.setText(info.getNotes());
		if (info instanceof Person) {
			Person person = (Person)info;
			orgBox.setNumberSelected(person.getOrganization());
			orgBox.refresh();			
			firstNameBox.setText(person.getFirstName());
		}
		if (info instanceof Organization) {
			Organization org = (Organization)info;
			vatRateBox.setText(vatRateFormat.format(org.vatRate));
			vatNumberBox.setText(org.getVATNumber());
			companyNumberBox.setText(org.getCompanyNumber());
		}
		refresh();
	}
	
	PostAddress getAddress()
	{
		PostAddress address = new PostAddress();
		address.setAddress(addressBox.getText());
		address.setPostCode(postCodeBox.getText());
		address.setCountryCode(countryBox.getSelectedCountry());
		address.setTown(townBox.getText());
		return address;
	}
	
	void setAddress(PostAddress address)
	{
		if (address!=null) {
			countryBox.setSelectedCountry(address.countryCode);
			addressBox.setText(address.address);
			postCodeBox.setText(address.postCode);
			townBox.setText(address.town);
		}
		else {
			countryBox.setSelectedCountry(null);
			addressBox.setText(null);
			postCodeBox.setText(null);
			townBox.setText(null);
		}
	}

	Contact getInput()
	{
		Contact info;
		if (this.info instanceof Person) info = new Person();
		else info = new Organization();
		info.setId(this.info.getId());
		info.setName(nameBox.getText());
		info.setPhone(phoneBox.getText());
		info.setEmail(emailBox.getText());
		info.setFax(faxBox.getText());
		info.setGroups(groupBox.getSelectedList());
		info.setAddress(getAddress());
		info.setNotes(notesBox.getText());
		if (info instanceof Person) {
			Person person = (Person)info;
			person.setFirstName(firstNameBox.getText());
			person.setOrganization(orgBox.getFirstSelected());
		}
		else {
			Organization org = (Organization)info;
			org.setVATNumber(vatNumberBox.getText());
			org.setVATRate(vatRateFormat.parse(vatRateBox.getText()));
			org.setCompanyNumber(companyNumberBox.getText());
		}
		return info;
	}
	
	public void saveChanges()
	{
		Contact input = getInput();
		mod.getService().save(input, new SaveCallback(input));
	}
	
	public void create()
	{
		mod.getService().createContact(getInput(), new CreateCallback());
	}
	
	public Contact getContact()
	{
		return info;
	}

}
